From 5b9b44e48377197b0f75780fc5d67c9909335433 Mon Sep 17 00:00:00 2001 From: "Ian.Campbell@xensource.com" Date: Wed, 9 Aug 2006 11:27:28 +0100 Subject: [PATCH] Make ballon and backend drivers fail gracefully if they are unable to initialize due to missing hypervisor support. Signed-off-by: Ian Campbell --- .../drivers/xen/balloon/balloon.c | 9 ++++ .../drivers/xen/blkback/blkback.c | 23 +++++---- .../drivers/xen/blktap/blktap.c | 50 ++++++++++++------- .../drivers/xen/netback/netback.c | 4 +- 4 files changed, 58 insertions(+), 28 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c index 95117b92cc..08ad6fd2b6 100644 --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c @@ -563,10 +563,14 @@ struct page *balloon_alloc_empty_page_range(unsigned long nr_pages) set_xen_guest_handle(reservation.extent_start, &gmfn); ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation); + if (ret == -ENOSYS) + goto err; BUG_ON(ret != 1); } else { ret = apply_to_page_range(&init_mm, vstart, PAGE_SIZE << order, dealloc_pte_fn, NULL); + if (ret == -ENOSYS) + goto err; BUG_ON(ret); } current_pages -= 1UL << order; @@ -583,6 +587,11 @@ struct page *balloon_alloc_empty_page_range(unsigned long nr_pages) set_page_count(page + i, 1); return page; + + err: + free_pages(vstart, order); + balloon_unlock(flags); + return NULL; } void balloon_dealloc_empty_page_range( diff --git a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c index ace6dbcc37..00f5785dd8 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c @@ -518,6 +518,19 @@ static int __init blkif_init(void) return -ENODEV; mmap_pages = blkif_reqs * BLKIF_MAX_SEGMENTS_PER_REQUEST; + +#ifdef CONFIG_XEN_IA64_DOM0_NON_VP + extern unsigned long alloc_empty_foreign_map_page_range( + unsigned long pages); + mmap_vstart = (unsigned long) + alloc_empty_foreign_map_page_range(mmap_pages); +#else /* ! ia64 */ + page = balloon_alloc_empty_page_range(mmap_pages); + if (page == NULL) + return -ENOMEM; + mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page)); +#endif + pending_reqs = kmalloc(sizeof(pending_reqs[0]) * blkif_reqs, GFP_KERNEL); pending_grant_handles = kmalloc(sizeof(pending_grant_handles[0]) * @@ -534,16 +547,6 @@ static int __init blkif_init(void) blkif_interface_init(); -#ifdef CONFIG_XEN_IA64_DOM0_NON_VP - extern unsigned long alloc_empty_foreign_map_page_range( - unsigned long pages); - mmap_vstart = (unsigned long) - alloc_empty_foreign_map_page_range(mmap_pages); -#else /* ! ia64 */ - page = balloon_alloc_empty_page_range(mmap_pages); - BUG_ON(page == NULL); - mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page)); -#endif printk("%s: reqs=%d, pages=%d, mmap_vstart=0x%lx\n", __FUNCTION__, blkif_reqs, mmap_pages, mmap_vstart); BUG_ON(mmap_vstart == 0); diff --git a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c index deb9e61933..329701ffe0 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c @@ -709,30 +709,19 @@ static void make_response(blkif_t *blkif, unsigned long id, /****************************************************************** * misc small helpers */ -/* FIXME: Return ENOMEM properly on failure to allocate additional reqs. */ -static void req_increase(void) +static int req_increase(void) { int i, j; struct page *page; unsigned long flags; + int ret; spin_lock_irqsave(&pending_free_lock, flags); + ret = -EINVAL; if (mmap_alloc >= MAX_PENDING_REQS || mmap_lock) goto done; - pending_reqs[mmap_alloc] = kzalloc(sizeof(pending_req_t) * - blkif_reqs, GFP_KERNEL); - pending_addrs[mmap_alloc] = kzalloc(sizeof(unsigned long) * - mmap_pages, GFP_KERNEL); - - if (!pending_reqs[mmap_alloc] || !pending_addrs[mmap_alloc]) { - kfree(pending_reqs[mmap_alloc]); - kfree(pending_addrs[mmap_alloc]); - WPRINTK("%s: out of memory\n", __FUNCTION__); - goto done; - } - #ifdef __ia64__ extern unsigned long alloc_empty_foreign_map_page_range( unsigned long pages); @@ -740,7 +729,11 @@ static void req_increase(void) alloc_empty_foreign_map_page_range(mmap_pages); #else /* ! ia64 */ page = balloon_alloc_empty_page_range(mmap_pages); - BUG_ON(page == NULL); + ret = -ENOMEM; + if (page == NULL) { + printk("%s balloon_alloc_empty_page_range gave NULL\n", __FUNCTION__); + goto done; + } /* Pin all of the pages. */ for (i=0; i